package com.example.tongyao.utils.tools;

import java.sql.Timestamp;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期时间处理类
 *
 * @version 2.0
 * @author tongyao
 * @since 2021-7-14
 */
public class DateUtils {

    //计算中间日期天数
    public static long daysBetween(Date one, Date two) {
        long difference =  (one.getTime()-two.getTime())/86400000;
        return Math.abs(difference);
    }

    //获取当天的开始时间
    public static java.util.Date getDayBegin() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    //获取当天的结束时间
    public static java.util.Date getDayEnd() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }
    //获取昨天的开始时间
    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }
    //获取昨天的结束时间
    public static Date getEndDayOfYesterDay() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }
    //获取明天的开始时间
    public static Date getBeginDayOfTomorrow() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, 1);

        return cal.getTime();
    }
    //获取明天的结束时间
    public static Date getEndDayOfTomorrow() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }


    /**
     * 根据某周里面的其中一个获取这个周的开始时间
     * @param date 某周中的日期
     * @return 某周开始的日期（返回字符串类型）
     * @throws Exception
     */
    public static String byWeekDateGetWeekStartChar(String date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        Date formatAfterDate = null;
        try {
            formatAfterDate = dateformat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(formatAfterDate);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(cal.getTime());
        return dateformat.format(calendar.getTimeInMillis());
    }

    /**
     * 根据某周里面的其中一个获取这个周的开始时间
     * @param date 某周中的日期
     * @return 某周开始的日期（返回时间Date日期类型）
     * @throws Exception
     */
    public static Date byWeekDateGetWeekStartDate(String date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        Date formatAfterDate = null;
        try {
            formatAfterDate = dateformat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(formatAfterDate);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(cal.getTime());
        return new Timestamp(calendar.getTimeInMillis());
    }




    //获取本周的开始时间
    public static Date getBeginDayOfWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }

    /**
     * 根据某周里面的其中一个获取这个周的结束时间
     * @param date 某周中的日期
     * @return 某周最后一天的日期（返回字符串类型）
     * @throws Exception
     */
    public static String byWeekDateGetWeekEndDateChar(String date){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date formatAfterDate = null;
        try {
            formatAfterDate = dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(formatAfterDate);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(cal.getTime());
        cal = Calendar.getInstance();
        cal.setTime(new Timestamp(calendar.getTimeInMillis()));
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        calendar = Calendar.getInstance();
        calendar.setTime(weekEndSta);
        //calendar.set(calendar.get(Calendar.YEAR),
        //        calendar.get(Calendar.MONTH),
        //        calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        //calendar.set(Calendar.MILLISECOND, 999);
        return dateFormat.format(calendar.getTimeInMillis());
    }

    /**
     * 根据某周里面的其中一个获取这个周的结束时间
     * @param date 某周中的日期
     * @return 某周最后一天的日期（返回时间Date日期类型）
     * @throws Exception
     */
    public static Date byWeekDateGetWeekEndDate(String date){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date formatAfterDate = null;
        try {
            formatAfterDate = dateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(formatAfterDate);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(cal.getTime());
        cal = Calendar.getInstance();
        cal.setTime(new Timestamp(calendar.getTimeInMillis()));
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        calendar = Calendar.getInstance();
        calendar.setTime(weekEndSta);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取本周的结束时间
    public static Date getEndDayOfWeek(){
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }


    /**
     * 通过开始时间结束时间获取中间周数
     * @param start
     * @param end
     * @return
     */
    public static String[] startEndTimeGetWeek(String start,String end){
        Calendar c_begin = new GregorianCalendar();
        Calendar c_end = new GregorianCalendar();
        DateFormatSymbols dfs = new DateFormatSymbols();
        String[] weeks = dfs.getWeekdays();
        c_begin.set(Integer.parseInt(start.split("-")[0]), Integer.parseInt(start.split("-")[1])-1,Integer.parseInt(start.split("-")[2])); //Calendar的月从0-11，所以4月是3.
        c_end.set(Integer.parseInt(end.split("-")[0]), Integer.parseInt(end.split("-")[1])-1,Integer.parseInt(end.split("-")[2])); //Calendar的月从0-11，所以5月是4.
        int count = 1;
        c_end.add(Calendar.DAY_OF_YEAR, 1); //结束日期下滚一天是为了包含最后一天
        List list = new ArrayList();
        while(c_begin.before(c_end)){
            //System.out.println("第"+count+"周 日期："+new java.sql.Date(c_begin.getTime().getTime())+", "+weeks[c_begin.get(Calendar.DAY_OF_WEEK)]);
            if(c_begin.get(Calendar.DAY_OF_WEEK)==Calendar.MONDAY){
                count++;
                list.add(new java.sql.Date(c_begin.getTime().getTime()));
                //System.out.println("第"+count+"周 日期："+new java.sql.Date(c_begin.getTime().getTime())+", "+weeks[c_begin.get(Calendar.DAY_OF_WEEK)]);
            }

            /*if(c_begin.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
                System.out.println(new java.sql.Date(c_begin.getTime().getTime()));
                //System.out.println("第"+count+"周 日期："+new java.sql.Date(c_begin.getTime().getTime())+", "+weeks[c_begin.get(Calendar.DAY_OF_WEEK)]);
            }*/
            c_begin.add(Calendar.DAY_OF_YEAR, 1);
        }

        String[] str = new String[list.size()];
        for (int i = 0;i< str.length;i++){
            str[i] = list.get(i).toString();
        }
        return str;
    }




    //获取本月的开始时间
    public static Date getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return getDayStartTime(calendar.getTime());
    }
    //获取本月的结束时间
    public static Date getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }



    //获取本年的开始时间
    public static java.util.Date getBeginDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        // cal.set
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);

        return getDayStartTime(cal.getTime());
    }
    //获取本年的结束时间
    public static java.util.Date getEndDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }
    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }
    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }
    //获取今年是哪一年
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    //获取本月是哪一月
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    //两个日期相减得到的天数
    public static int getDiffDays(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null) {
            throw new IllegalArgumentException("getDiffDays param is null!");
        }
        long diff = (endDate.getTime() - beginDate.getTime())
                / (1000 * 60 * 60 * 24);
        int days = new Long(diff).intValue();
        return days;
    }

    //两个日期相减得到的毫秒数
    public static long dateDiff(Date beginDate, Date endDate) {
        long date1ms = beginDate.getTime();
        long date2ms = endDate.getTime();
        return date2ms - date1ms;
    }

    //获取两个日期中的最大日期
    public static Date max(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return beginDate;
        }
        return endDate;
    }

    //获取两个日期中的最小日期
    public static Date min(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return endDate;
        }
        return beginDate;
    }

    //返回某月该季度的第一个月
    public static Date getFirstSeasonDate(Date date) {
        final int[] SEASON = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int sean = SEASON[cal.get(Calendar.MONTH)];
        cal.set(Calendar.MONTH, sean * 3 - 3);
        return cal.getTime();
    }
    //返回某个日期下几天的日期
    public static Date getNextDay(Date date, int i) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) + i);
        return cal.getTime();
    }

    //返回某个日期前几天的日期
    public static Date getFrontDay(Date date, int i) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) - i);
        return cal.getTime();
    }

    //获取某年某月到某年某月按天的切片日期集合（间隔天数的日期集合）
    public static List getTimeList(int beginYear, int beginMonth, int endYear,
                                   int endMonth, int k) {
        List list = new ArrayList();
        if (beginYear == endYear) {
            for (int j = beginMonth; j <= endMonth; j++) {
                list.add(getTimeList(beginYear, j, k));

            }
        } else {
            {
                for (int j = beginMonth; j < 12; j++) {
                    list.add(getTimeList(beginYear, j, k));
                }

                for (int i = beginYear + 1; i < endYear; i++) {
                    for (int j = 0; j < 12; j++) {
                        list.add(getTimeList(i, j, k));
                    }
                }
                for (int j = 0; j <= endMonth; j++) {
                    list.add(getTimeList(endYear, j, k));
                }
            }
        }
        return list;
    }

    //获取某年某月按天切片日期集合（某个月间隔多少天的日期集合）
    public static List getTimeList(int beginYear, int beginMonth, int k) {
        List list = new ArrayList();
        Calendar begincal = new GregorianCalendar(beginYear, beginMonth, 1);
        int max = begincal.getActualMaximum(Calendar.DATE);
        for (int i = 1; i < max; i = i + k) {
            list.add(begincal.getTime());
            begincal.add(Calendar.DATE, k);
        }
        begincal = new GregorianCalendar(beginYear, beginMonth, max);
        list.add(begincal.getTime());
        return list;
    }


    //获取某年某月的第一天日期
    public static Date getStartMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getTime();
    }

    //获取某年某月的最后一天日期
    public static Date getEndMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(year, month - 1, day);
        return calendar.getTime();
    }

    /**
     * 获取开始与结束时间之间的日期列表
     * @param startDate
     * @param endDate
     * @return
     */
    public static String[] getBetweenDateList(String startDate, String endDate) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date startTime = simpleDateFormat.parse(startDate);
        Date endTime = simpleDateFormat.parse(endDate);
        List<String> dateList = new ArrayList<String>();
        while(startTime.compareTo(endTime) != 1) {
            dateList.add(simpleDateFormat.format(startTime));
            startTime.setTime(startTime.getTime() + 1000 * 60 * 60 * 24);
        }
        String[] str = new String[dateList.size()];
        for (int i = 0;i < dateList.size();i++){
            str[i] = dateList.get(i);
        }
        return str;
    }

    /**
     * 根据日期取得星期几
     * @param time
     * @return
     * @throws Exception
     */
    public static String getWeek(String time) throws Exception{
        Calendar ca = Calendar.getInstance();
        String[] str = time.split("-");
        ca.set(Integer.parseInt(str[0]),Integer.parseInt(str[1])-1,Integer.parseInt(str[2]));
        String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
        int index = ca.get(Calendar.DAY_OF_WEEK)-1;
        return weekDays[index];
    }

    /**
     * 获取指定月的开始结束时间
     * @param time
     * @return
     */
    public static String getMonthStartEnd(String time){
        String str = "";
        String[] date = time.split("-");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Integer.parseInt(date[0]), Integer.parseInt(date[1]) - 1, 1);

        calendar.setTime(calendar.getTime());
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        str = str + new Timestamp(calendar.getTimeInMillis()).toString().split(" ")[0]+"/";

        calendar.set(Integer.parseInt(date[0]), Integer.parseInt(date[1]) - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(Integer.parseInt(date[0]), Integer.parseInt(date[1]) - 1, day);

        calendar.setTime(calendar.getTime());
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        str = str + new Timestamp(calendar.getTimeInMillis()).toString().split(" ")[0];
        return str;
    }

    /**
     * 获取从开始时间到结束时间中的有几个月
     * @param startTime
     * @param endTime
     * @return
     * @throws Exception
     */
    public static String[] getMonthAll(String startTime,String endTime) throws Exception{
        Date startDate = new SimpleDateFormat("yyyy-MM").parse(startTime);
        Date endDate = new SimpleDateFormat("yyyy-MM").parse(endTime);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        // 获取开始年份和开始月份
        int startYear = calendar.get(Calendar.YEAR);
        int startMonth = calendar.get(Calendar.MONTH);
        // 获取结束年份和结束月份
        calendar.setTime(endDate);
        int endYear = calendar.get(Calendar.YEAR);
        int endMonth = calendar.get(Calendar.MONTH);
        //
        List<String> list = new ArrayList<String>();
        for (int i = startYear; i <= endYear; i++) {
            String date = "";
            if (startYear == endYear) {
                for (int j = startMonth; j <= endMonth; j++) {
                    if (j < 9) {
                        date = i + "-0" + (j + 1);
                    } else {
                        date = i + "-" + (j + 1);
                    }
                    list.add(date);
                }

            } else {
                if (i == startYear) {
                    for (int j = startMonth; j < 12; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                } else if (i == endYear) {
                    for (int j = 0; j <= endMonth; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                } else {
                    for (int j = 0; j < 12; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                }

            }

        }

        // 所有的月份已经准备好
        //System.out.println(list);
        String[] str = new String[list.size()];
        for(int i = 0;i < list.size();i++){
            str[i] = list.get(i);
        }
        return str;
    }

    //获取年的开始日期和结束日期
    public static String getYearStartEnd(String year){
        return year+"-01-01/"+year+"-12-31";
    }

    //获取开始时间和结束时间终将有几年
    public static int[] getYearAll(int startYear,int endYear){
        int startTime = startYear;
        int endTime = endYear;
        int[] year = new int[endTime-startTime+1];
        for(int i = 0;i<year.length;i++){
            year[i] = startTime;
            startTime++;
        }
        return year;
    }

    public static String[] getYearAll(String startYear,String endYear){
        int startTime = Integer.parseInt(startYear.split("-")[0]);
        int endTime = Integer.parseInt(endYear.split("-")[0]);
        String[] year = new String[endTime-startTime+1];
        for(int i = 0;i<year.length;i++){
            year[i] = startTime+"";
            startTime++;
        }
        return year;
    }

}